package com.yh.utils.extract.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.DruidDataSourceStatManager;
import com.yh.utils.extract.model.DataSourceDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


@Slf4j
public class DynamicDatasource  extends AbstractRoutingDataSource {

    private static final ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();

    private Map<Object, Object> dynamicTargetDataSources=new HashMap<>();
    @Autowired
    private Environment env;
    @Autowired
    DataSourcePropertes dataSourcePropertes;
    @Override
    protected Object determineCurrentLookupKey() {
        String dataSource = dataSourceKey.get();
        log.debug("thread:{},链接数据源:{}",Thread.currentThread().getName(),dataSource);
        return dataSource;
    }

    public static void setDataSourceKey(String dataSource) {
        log.debug("thread:{},设置数据源:{}",Thread.currentThread().getName(),dataSource);
        dataSourceKey.set(dataSource);
    }

    public static void clearDataSourceType() {
        log.debug("thread:{},删除数据源:{}",Thread.currentThread().getName());
        dataSourceKey.remove();
    }

    // 创建数据源
    public boolean createDataSource(DataSourceDO dataSourceDO) {
        try {
            try { // 排除连接不上的错误
                Class.forName(dataSourceDO.getDriverClassName());
                DriverManager.getConnection(dataSourceDO.getUrl(), dataSourceDO.getUserName(), dataSourceDO.getPassWord());// 相当于连接数据库
            } catch (Exception e) {
                return false;
            }
            @SuppressWarnings("resource")
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setName(dataSourceDO.getKey());
            druidDataSource.setDriverClassName(dataSourceDO.getDriverClassName());
            druidDataSource.setUrl(dataSourceDO.getUrl());
            druidDataSource.setUsername(dataSourceDO.getUserName());
            druidDataSource.setPassword(dataSourceDO.getPassWord());
            dataSourcePropertes.setDataSourcePropeties(druidDataSource);
            DataSource createDataSource = (DataSource) druidDataSource;
            druidDataSource.init();
            Map<Object, Object> tempDynamicTargetDataSources = this.dynamicTargetDataSources;
            log.info("新增数据源{}",dataSourceDO.getKey());
            tempDynamicTargetDataSources.put(dataSourceDO.getKey(), createDataSource);
            setTargetDataSources(this.dynamicTargetDataSources);
            super.afterPropertiesSet();
            return true;
        } catch (Exception e) {
            log.error(e + "");
            return false;
        }
    }

    // 删除数据源
    public boolean delDatasources(String datasourceid) {
        Map<Object, Object> tempDynamicTargetDataSources = this.dynamicTargetDataSources;
        if (tempDynamicTargetDataSources.containsKey(datasourceid)) {
            Set<DruidDataSource> druidDataSourceInstances = DruidDataSourceStatManager.getDruidDataSourceInstances();
            for (DruidDataSource druidDataSource : druidDataSourceInstances) {
                if (datasourceid.equals(druidDataSource.getName())) {
                    log.info("删除数据源{}",datasourceid);
                    Object dataSource = tempDynamicTargetDataSources.get(datasourceid);
                    tempDynamicTargetDataSources.remove(datasourceid);
                    DruidDataSourceStatManager.removeDataSource(dataSource);
                    setTargetDataSources(tempDynamicTargetDataSources);// 将map赋值给父类的TargetDataSources
                    super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
                    return true;
                }
            }
            return false;
        } else {
            return false;
        }
    }

    // 清空数据源
    public void clearDataSource() {
        Map<Object, Object> tempDynamicTargetDataSources = this.dynamicTargetDataSources;
        for(Map.Entry<Object, Object> entry:tempDynamicTargetDataSources.entrySet()){
            String datasourceid = (String)entry.getKey();
            delDatasources(datasourceid);
        }
    }


}
